home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / POVSRC / SOURCE / TextEditor.c < prev    next >
Text File  |  1994-02-04  |  23KB  |  980 lines

  1. /*==============================================================================
  2. Project:    POV-Ray
  3.  
  4. Version:    2.2
  5.  
  6. File:    TextEditor.c
  7.  
  8. Description:
  9.     This file contains Macintosh-specific routines for the
  10.     source code text editor.
  11. ------------------------------------------------------------------------------
  12. Author:
  13.     Symantec, mods by Jim Nitchals, more mods & Think 6 updates by Eduard [esp] Schwan
  14. ------------------------------------------------------------------------------
  15.     from Persistence of Vision Raytracer
  16.     Copyright 1993 Persistence of Vision Team
  17. ------------------------------------------------------------------------------
  18.     NOTICE: This source code file is provided so that users may experiment
  19.     with enhancements to POV-Ray and to port the software to platforms other 
  20.     than those supported by the POV-Ray Team.  There are strict rules under
  21.     which you are permitted to use this file.  The rules are in the file
  22.     named POVLEGAL.DOC which should be distributed with this file. If 
  23.     POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  24.     Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  25.     Forum.  The latest version of POV-Ray may be found there as well.
  26.  
  27.     This program is based on the popular DKB raytracer version 2.12.
  28.     DKBTrace was originally written by David K. Buck.
  29.     DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  30. ------------------------------------------------------------------------------
  31. More Info:
  32.     This Macintosh version of POV-Ray was created and compiled by Jim Nitchals
  33.     (Think 5.0) and Eduard Schwan (MPW 3.2), based (loosely) on the original
  34.     port by Thomas Okken and David Lichtman, with some help from Glenn Sugden.
  35.  
  36.     For bug reports regarding the Macintosh version, you should contact:
  37.     Eduard [esp] Schwan
  38.         CompuServe: 71513,2161
  39.         Internet: jl.tech@applelink.apple.com
  40.         AppleLink: jl.tech
  41.     Jim Nitchals
  42.         Compuserve: 73117,3020
  43.         America Online: JIMN8
  44.         Internet: jimn8@aol.com -or- jimn8@applelink.apple.com
  45.         AppleLink: JIMN8
  46. ------------------------------------------------------------------------------
  47. Change History:
  48.     920815    [jln]    version 1.0 Mac released.
  49.     920908    [esp]    version 1.1 alpha Mac
  50.     920912    [esp]    changed window id to 1000 & moved #define here from POVMac.h
  51.     921110    [esp]    Added TextEditor.h file & pulled in defs to there
  52.     921207    [esp]    Added code to handle zoom box
  53.     921211    [esp]    Fixed bug in Open: if open failed, left New & Open items dimmed
  54.     930710    [esp]    fixed "cancelling of save-as dialog" logic
  55.     930817    [esp]    Added FlushVol calls in SaveFile and SaveAs to force disk update
  56.     931001    [esp]    version 2.0 finished (Released on 10/4/93)
  57.     931119    [djh]    2.0.1 conditionally compiles for PPC machines, keyword __powerc
  58. ==============================================================================*/
  59.  
  60.  
  61. #include "TextEditor.h"
  62.  
  63. /*==== Standard C headers ====*/
  64. #include <stdio.h>
  65.  
  66. /*==== Mac toolbox headers ====*/
  67. // NOTE: _H_MacHeaders_ is defined by Think C if it is using
  68. // precompiled headers.  This is only for compilation speed improvement.
  69. #if !defined(_H_MacHeaders_)
  70. #include <types.h>        // basic types
  71. #include <desk.h>        // SystemEdit, etc.
  72. #include <errors.h>        // noErr, etc.
  73. #include <files.h>        // FSOpen, etc. 
  74. #include <fonts.h>        // monaco, etc. 
  75. #include <memory.h>        // NewHandle, etc. 
  76. #include <menus.h>        // MenuHandle, etc. 
  77. #include <packages.h>    // SFGetFile, etc. 
  78. #include <scrap.h>        // ZeroScrap, etc. 
  79. #include <toolutils.h>    // watchCursor, etc. 
  80. #include <windows.h>    // SizeWindow, etc. 
  81. #endif // _H_MacHeaders_
  82.  
  83.  
  84. /*==== POV Mac Library routines =====*/
  85.  
  86. #include "POVLib.h"
  87. #include "ImageWindow.h" // CloseImageWindow(), gImageWindIsValid
  88.  
  89.  
  90. /*==== globals (external scope) ====*/
  91.  
  92. #if defined(__powerc)
  93. extern RoutineDescriptor gScrollRD;
  94. #endif
  95.  
  96. WindowPtr            gSrcWind_Window;
  97. TEHandle            gSrcWind_TEH;
  98. Boolean                gSrcWind_dirty;
  99. Boolean                gSrcWind_visible;
  100. Str255                 gSrcWind_FileName;
  101. short                gSrcWind_VRefNum;
  102. ControlHandle         gSrcWind_VScroll;
  103.  
  104.  
  105. /*==== globals (local scope) ====*/
  106.  
  107. static WindowRecord    wRecord;
  108. static int            linesInFolder;
  109.  
  110.  
  111. // ==============================================
  112. #define SrcWind_WindID     1000
  113. #define ErrorAlert        256
  114. #define    AdviseAlert        257
  115.  
  116. #define fmNew            1
  117. #define fmRevert        7
  118. #define fmPageSetUp        9
  119. #define fmPrint            10
  120. #define fmQuit            13
  121.  
  122. #define aaSave            1
  123. #define aaDiscard        2
  124. #define aaCancel        3
  125.  
  126. #define SBarWidth        15
  127.  
  128. #define    ours(w)        ((gSrcWind_Window != NULL) && (w == gSrcWind_Window))
  129.  
  130. #define    kUntitledFName    "\pUntitled.POV"
  131.  
  132.  
  133. // ==============================================
  134. int SetUpFiles(void)
  135. {
  136.     pStrCopy(kUntitledFName, gSrcWind_FileName);
  137.     gSrcWind_VRefNum = 0;
  138.     return 0; // should be void fn!?
  139. }
  140.  
  141.  
  142.  
  143. // ==============================================
  144. int DoFile(int item)
  145. {
  146.     short     vRef, refNum;
  147.     Str255    fn;
  148.  
  149.     switch (item) {
  150.  
  151.         case fmn_open:
  152.             HideWindow(gSrcWind_Window);    /* gives a sense of closing the old file. */
  153.             if (OldFile(fn, &vRef))
  154.             {
  155.                 gSrcWind_VRefNum = 0;
  156.                 gSrcWind_dirty = 0;
  157.                 if (FSOpen(fn, vRef, &refNum)==noErr) {
  158.                     if (ReadFile(refNum, gSrcWind_TEH)) {
  159.                         pStrCopy(fn, gSrcWind_FileName);
  160.                         gSrcWind_VRefNum = vRef;
  161.                         SetWTitle(gSrcWind_Window, gSrcWind_FileName);
  162.                     }
  163.                     if (FSClose(refNum)==noErr) ;
  164.                     ShowWindow(gSrcWind_Window);
  165.                     gSrcWind_visible = TRUE;
  166.                     TESetSelect(0, 0, gSrcWind_TEH);
  167.                     ShowSelect();
  168.                 }
  169.                 else
  170.                     FileError("\pError opening ", fn);
  171.             }
  172.             break;
  173.  
  174.         case fmn_close:
  175.             if (DoFile(render_file))    // recurse.
  176.                 CloseMyWindow();
  177.             break;
  178.  
  179.         case render_file:
  180.             if (gSrcWind_dirty)
  181.             {
  182.                 ParamText("\pSave changes to “",
  183.                         gSrcWind_FileName,
  184.                         "\p”?", "\p");
  185.                 switch (Alert(AdviseAlert, 0L))
  186.                 {
  187.                 case aaSave:
  188.                     if (gSrcWind_VRefNum == 0)
  189.                     { // create new file
  190.                         pStrCopy(gSrcWind_FileName, fn);
  191.                         if (!SaveAs(fn, &vRef))
  192.                             return(0);
  193.                     }
  194.                      else // save existing file
  195.                         if (!SaveFile(gSrcWind_FileName, gSrcWind_VRefNum))
  196.                             return(0);
  197.                      break;
  198.                  case aaCancel:
  199.                     return(0);
  200.                  case aaDiscard:
  201.                     gSrcWind_dirty = 0;
  202.                  }
  203.              }
  204.             break;
  205.  
  206.         case fmn_save:
  207.             // if file already open
  208.             if (gSrcWind_VRefNum != 0)
  209.             {
  210.                 if (!SaveFile(gSrcWind_FileName, gSrcWind_VRefNum))
  211.                     return(0);
  212.                 break;
  213.             }
  214.             // else drop through to here..
  215.  
  216.         case fmn_saveas:
  217.             pStrCopy(gSrcWind_FileName, fn);
  218.             if (SaveAs(fn, &vRef))
  219.             {
  220.                 pStrCopy(fn, gSrcWind_FileName);
  221.                 gSrcWind_VRefNum = vRef;
  222.                 SetWTitle(gSrcWind_Window, gSrcWind_FileName);
  223.             }
  224.             else
  225.                 return(0);
  226.             break;
  227.  
  228.         case fmRevert:
  229.             ParamText("\pRevert to last saved version of “",
  230.                     gSrcWind_FileName, "\p”?", "\p");
  231.             switch (Alert(AdviseAlert, 0L)) {
  232.             case aaSave:
  233.                 HidePen();
  234.                 TESetSelect(0, (**gSrcWind_TEH).teLength, gSrcWind_TEH);
  235.                 ShowPen();
  236.                 TEDelete(gSrcWind_TEH);
  237.                 if ((gSrcWind_VRefNum != 0) &&
  238.                     (FSOpen(gSrcWind_FileName, gSrcWind_VRefNum, &refNum)==noErr))
  239.                 {
  240.                     gSrcWind_dirty = !ReadFile(refNum, gSrcWind_TEH); 
  241.                     if (FSClose(refNum)==noErr) ;
  242.                 }
  243.                 ShowWindow(gSrcWind_Window);
  244.                 gSrcWind_visible = TRUE;
  245.                 UpdateWindow(gSrcWind_Window);
  246.              case aaCancel:
  247.              case aaDiscard:
  248.                 return(0);
  249.              }
  250.     
  251.             break;
  252.  
  253. #if defined(_DO_PRINTING_SOMEDAY_)
  254.         case fmPageSetUp:
  255.             DoPageSetUp();
  256.             break;
  257.         case fmPrint:
  258.             PrintText( (**gSrcWind_TEH).hText, (long)(**gSrcWind_TEH).teLength, (GrafPtr)gSrcWind_Window,
  259.                             StringWidth("\pmmmm"));
  260.             break;
  261. #endif // DO_PRINTING_SOMEDAY
  262.         case fmQuit: 
  263.             if (DoFile(fmn_close))
  264.                 ExitToShell();
  265.     }
  266.     return(1);
  267. }
  268.  
  269.  
  270.  
  271. // ==============================================
  272. static Point SFwhere;
  273. static SFReply reply;
  274.  
  275.  
  276. int SaveAs(Str255 fn, short *vRef)
  277. {
  278.     short refNum;
  279.     
  280.     if (NewFile(fn, vRef)) 
  281.         if (!CreateFile(fn, vRef, &refNum))
  282.         {
  283.             FileError("\pError creating file ", fn);
  284.             return (0);
  285.         }
  286.         else
  287.         {
  288.             char hstate;
  289.             
  290.             hstate = HGetState((**gSrcWind_TEH).hText);
  291.             HLock((**gSrcWind_TEH).hText);
  292.             if (WriteFile(refNum, (*(**gSrcWind_TEH).hText), (long)(**gSrcWind_TEH).teLength))
  293.                 FileError("\pError writing file ", fn);
  294.             HSetState((**gSrcWind_TEH).hText, hstate);
  295.             FSClose(refNum);
  296.             gSrcWind_dirty = 0;
  297.             // flush any buffers to disk
  298.             FlushVol(NULL, *vRef);
  299.             return(1);
  300.         }
  301. }
  302.  
  303.  
  304.  
  305. // ==============================================
  306. int SaveFile(Str255 fn, short vRef)
  307. {
  308.     short refNum;
  309.     if (FSOpen(fn, vRef, &refNum) != noErr)
  310.     {
  311.         FileError("\pError opening file ", fn);
  312.         return (1);
  313.     }
  314.     else
  315.     {
  316.         char hstate;
  317.         
  318.         hstate = HGetState((**gSrcWind_TEH).hText);
  319.         HLock((**gSrcWind_TEH).hText);
  320.         if (WriteFile(refNum, (*(**gSrcWind_TEH).hText), (long)(**gSrcWind_TEH).teLength))
  321.             FileError("\pError writing file ", fn);
  322.         HSetState((**gSrcWind_TEH).hText, hstate);
  323.         gSrcWind_dirty = 0;
  324.         FSClose(refNum);
  325.         // flush any buffers to disk
  326.         FlushVol(NULL, vRef);
  327.         return(1);
  328.     }
  329. }
  330.  
  331.  
  332.  
  333. // ==============================================
  334. int NewFile(Str255 fn, short *vRef)
  335. {
  336.     GetBestDialogPos(&SFwhere);
  337.     SFPutFile(SFwhere, "\pSave POV-Ray text file as", fn, 0L, &reply);
  338.     if (!reply.good)
  339.         return (0);
  340.     else {
  341.         pStrCopy(reply.fName, fn);
  342.         *vRef = reply.vRefNum;
  343.         return(1);
  344.     }
  345. }
  346.  
  347.  
  348.  
  349. // ==============================================
  350. int OldFile(Str255 fn, short *vRef)
  351. {
  352.     SFTypeList    myTypes;
  353.     
  354.     myTypes[0]='TEXT';
  355.  
  356.     GetBestDialogPos(&SFwhere);
  357.     SFGetFile(SFwhere, "\p", 0L, 1, myTypes, 0L, &reply );
  358.  
  359.     if (!reply.good)
  360.         return (0);
  361.     else {
  362.         pStrCopy(reply.fName, fn);
  363.         *vRef = reply.vRefNum;
  364.         return(1);
  365.     }
  366. }
  367.  
  368.  
  369.  
  370. // ==============================================
  371. int CreateFile(Str255 fn, short *vRef, short *theRef)
  372. {
  373.     OSErr io;
  374.     
  375.     io=Create(fn, *vRef, kAppSignature, 'TEXT');
  376.     if ((io == noErr) || (io == dupFNErr))
  377.         io = FSOpen(fn, *vRef, theRef );
  378.  
  379.     return ((io == noErr) || (io == dupFNErr));
  380. }
  381.  
  382.  
  383.  
  384. // ==============================================
  385. int WriteFile(short refNum, char *p, long num)
  386. {
  387.     OSErr io;            
  388.     /* gee,    somebody should check the return code for errors */
  389.     io=FSWrite(refNum, &num, p);
  390.     if (io)
  391.         return(io);
  392.     io=SetEOF(refNum, num);
  393.     return(io);
  394. }
  395.  
  396.  
  397.  
  398. // ==============================================
  399. int ReadFile(short refNum, TEHandle textH)
  400. {
  401.     char    buffer[256];
  402.     long    count;
  403.     OSErr        io;
  404.     
  405.     (**textH).selStart = 0;
  406.     (**textH).selEnd = (**textH).teLength;
  407.     TEDelete(textH);
  408.     GetEOF(refNum, &count);
  409.     if (count > 32767L)
  410.         return (999);
  411.     do {
  412.         count = 256;
  413.         io = FSRead(refNum, &count, &buffer);
  414.         TEInsert(&buffer, count, textH);
  415.     } while (io==noErr);
  416.     return (io == eofErr);
  417. }
  418.  
  419.  
  420.  
  421. // ==============================================
  422. /* copies a pascal string from p1 to p2 */
  423. int pStrCopy(StringPtr p1, StringPtr p2)
  424. {
  425.     register int len = *p1;    // added asignment
  426.     
  427.     *(p2++) = *(p1++);            // added parens
  428.     while (--len>=0) *(p2++)=*(p1++);    // added parens
  429.     return 0; // should be void fn!?
  430. }
  431.  
  432.  
  433.  
  434. // ==============================================
  435. int FileError(Str255 s, Str255 f)
  436. {
  437.     ParamText(s, f,"\p", "\p");
  438.     Alert(ErrorAlert, 0L);
  439.     return 0; // should be void fn!?
  440. }
  441.  
  442.  
  443.  
  444. // ==============================================
  445. void PreInitWindows(void)
  446. {
  447.     if (gSrcWind_Window == 0)
  448.     {
  449.         SetUpWindows();
  450.         HideWindow(gSrcWind_Window);    /* just in case it's already visible */
  451.     }
  452. }
  453.  
  454.  
  455.  
  456. // ==============================================
  457. int SetUpWindows(void)
  458. {
  459.     Rect    viewRect;
  460.     Rect    vScrollRect;
  461.  
  462.     gSrcWind_Window = GetNewWindow(SrcWind_WindID, &wRecord, (WindowPtr)NULL);
  463.     if (!gSrcWind_Window)
  464.         return 1;
  465.     SetPort(gSrcWind_Window);
  466.     TextFont(monaco);
  467.     TextSize(9);
  468.     vScrollRect = (*gSrcWind_Window).portRect;
  469.     vScrollRect.left = vScrollRect.right-SBarWidth;
  470.     vScrollRect.right += 1;
  471.     vScrollRect.bottom -= SBarWidth-1;
  472.     vScrollRect.top -= 1;
  473.     gSrcWind_VScroll = NewControl( gSrcWind_Window, &vScrollRect, "\pSrcVScroll", 1, 0, 0, 0,
  474.         scrollBarProc, 0L);
  475.  
  476.     viewRect = qd.thePort->portRect;
  477.     viewRect.right -= SBarWidth;
  478.     viewRect.bottom -= SBarWidth;
  479.     InsetRect(&viewRect, 4, 4);
  480.     gSrcWind_TEH = TENew(&viewRect, &viewRect);
  481.     SetView((WindowPtr) qd.thePort);
  482.     gSrcWind_dirty = 0;
  483.     return 0; // should be void fn!?
  484. }
  485.  
  486.  
  487.  
  488. // ==============================================
  489. int AdjustText(void)
  490. {
  491.     int        oldScroll, newScroll, delta;
  492.     
  493.     oldScroll = (**gSrcWind_TEH).viewRect.top - (**gSrcWind_TEH).destRect.top;
  494.     newScroll = GetCtlValue(gSrcWind_VScroll) * (**gSrcWind_TEH).lineHeight;
  495.     delta = oldScroll - newScroll;
  496.     if (delta != 0)
  497.       TEScroll(0, delta, gSrcWind_TEH);
  498.     SetVScroll();
  499.     return 0; // should be void fn!?
  500. }
  501.  
  502.  
  503.  
  504. // ==============================================
  505. int SetVScroll(void)
  506. {
  507.     register int    n;
  508.     
  509.     n = (**gSrcWind_TEH).nLines-linesInFolder;
  510.  
  511.     if ((**gSrcWind_TEH).teLength > 0 && (*((**gSrcWind_TEH).hText))[(**gSrcWind_TEH).teLength-1]=='\r')
  512.         n++;
  513.  
  514.     SetCtlMax(gSrcWind_VScroll, n > 0 ? n : 0);
  515.     ShowControl(gSrcWind_VScroll);
  516.     return 0; // should be void fn!?
  517. }
  518.  
  519.  
  520.  
  521. // ==============================================
  522. int ShowSelect(void)
  523. {
  524.     register    int        topLine, bottomLine, theLine;
  525.     
  526.     SetVScroll();
  527.     AdjustText();
  528.     
  529.     topLine = GetCtlValue(gSrcWind_VScroll);
  530.     bottomLine = topLine + linesInFolder;
  531.     
  532.     // count up the lines to current
  533.     if ((**gSrcWind_TEH).selStart < (**gSrcWind_TEH).lineStarts[topLine] ||
  534.             (**gSrcWind_TEH).selStart >= (**gSrcWind_TEH).lineStarts[bottomLine]) {
  535.         for (    theLine = 0;
  536.                 (**gSrcWind_TEH).selStart >= (**gSrcWind_TEH).lineStarts[theLine];
  537.                 theLine++)
  538.             ;
  539.         SetCtlValue(gSrcWind_VScroll, theLine - linesInFolder / 2);
  540.         AdjustText();
  541.     }
  542.     return 0; // should be void fn!?
  543. }
  544.  
  545.  
  546.  
  547. // ==============================================
  548. void SelectAllText(void)
  549. {    
  550.     TESetSelect(0, -1, gSrcWind_TEH);
  551.     SetVScroll();
  552.     AdjustText();    
  553. }
  554.  
  555.  
  556.  
  557. // ==============================================
  558. int SetView(WindowPtr w)
  559. {
  560.     (**gSrcWind_TEH).viewRect = w->portRect;
  561.     (**gSrcWind_TEH).viewRect.right -= SBarWidth;
  562.     (**gSrcWind_TEH).viewRect.bottom -= SBarWidth;
  563.     InsetRect(&(**gSrcWind_TEH).viewRect, 4, 4);
  564.  
  565.     linesInFolder = ((**gSrcWind_TEH).viewRect.bottom-(**gSrcWind_TEH).viewRect.top)/(**gSrcWind_TEH).lineHeight;
  566.     (**gSrcWind_TEH).viewRect.bottom = (**gSrcWind_TEH).viewRect.top + (**gSrcWind_TEH).lineHeight*linesInFolder;
  567.     (**gSrcWind_TEH).destRect.right = (**gSrcWind_TEH).viewRect.right;
  568.     TECalText(gSrcWind_TEH);
  569.     return 0; // should be void fn!?
  570. }
  571.  
  572.  
  573.  
  574. // ==============================================
  575. int UpdateWindow(WindowPtr theWindow)
  576. {
  577.     GrafPtr    savePort;
  578.     
  579.     GetPort(&savePort);
  580.     SetPort(theWindow);
  581.  
  582.     BeginUpdate(theWindow);
  583.     EraseRect(&theWindow->portRect);
  584.     DrawControls(theWindow);
  585.     DrawGrowIcon(theWindow);
  586.     TEUpdate(&theWindow->portRect, gSrcWind_TEH);
  587.     EndUpdate(theWindow);
  588.  
  589.     SetPort(savePort);
  590.     return 0; // should be void fn!?
  591. }
  592.  
  593.  
  594.  
  595. // ==============================================
  596. pascal void ScrollProc(ControlHandle theControl, short theCode)
  597. {
  598.     int    pageSize;
  599.     int    scrollAmt;
  600.     int oldCtl;
  601.     
  602.     if (theCode == 0)
  603.         return ;
  604.     
  605.     pageSize = ((**gSrcWind_TEH).viewRect.bottom-(**gSrcWind_TEH).viewRect.top) / 
  606.             (**gSrcWind_TEH).lineHeight - 1;
  607.             
  608.     switch (theCode) {
  609.         case inUpButton: 
  610.             scrollAmt = -1;
  611.             break;
  612.         case inDownButton: 
  613.             scrollAmt = 1;
  614.             break;
  615.         case inPageUp: 
  616.             scrollAmt = -pageSize;
  617.             break;
  618.         case inPageDown: 
  619.             scrollAmt = pageSize;
  620.             break;
  621.     }
  622.  
  623.     oldCtl = GetCtlValue(theControl);
  624.     SetCtlValue(theControl, oldCtl+scrollAmt);
  625.  
  626.     AdjustText();
  627. }
  628.  
  629.  
  630.  
  631. // ==============================================
  632. int DoContent(WindowPtr theWindow, EventRecord *theEvent)
  633. {
  634.     short            cntlCode;
  635.     ControlHandle     theControl;
  636.     GrafPtr            savePort;
  637.     
  638.     GetPort(&savePort);
  639.     SetPort(theWindow);
  640.  
  641.     GlobalToLocal(&theEvent->where);
  642.     if ((cntlCode = FindControl(theEvent->where, theWindow, &theControl)) == 0) {
  643.         if (PtInRect(theEvent->where, &(**gSrcWind_TEH).viewRect))
  644.             TEClick(theEvent->where, (theEvent->modifiers & shiftKey)!=0, gSrcWind_TEH);
  645.     } else if (cntlCode == inThumb) {
  646.         TrackControl(theControl, theEvent->where, 0L);
  647.         AdjustText();
  648.     } else
  649. #if defined(__powerc)
  650.         TrackControl(theControl, theEvent->where, (ControlActionUPP)&gScrollRD);
  651. #else
  652.         TrackControl(theControl, theEvent->where, (ProcPtr)&ScrollProc);
  653. #endif
  654.  
  655.     SetPort(savePort);
  656.     return 0; // should be void fn!?
  657. }
  658.  
  659.  
  660.  
  661. // ==============================================
  662. void MyResizeWindow(WindowPtr w, short h, short v)
  663. {
  664.     Rect    oldHorizBar;
  665.     Rect     r;
  666.     
  667.     SetPort(w);
  668.  
  669.     oldHorizBar = w->portRect;
  670.     oldHorizBar.top = oldHorizBar.bottom - (SBarWidth+1);
  671.  
  672.     SizeWindow(w, h, v, false);
  673.  
  674.     // remember this new size in prefs
  675.     GetGlobalWindowRect(w, &(**gFilePrefs_h).srcWind_pos);
  676.  
  677.     InvalRect(&w->portRect);
  678.     
  679.     SetView(w);
  680.  
  681.     EraseRect(&oldHorizBar);
  682.     
  683.     MoveControl(gSrcWind_VScroll, w->portRect.right - SBarWidth, w->portRect.top-1);
  684.     SizeControl(gSrcWind_VScroll, SBarWidth+1, w->portRect.bottom - w->portRect.top-(SBarWidth-2));
  685.     r = (**gSrcWind_VScroll).contrlRect;
  686.     ValidRect(&r);
  687.  
  688.     SetVScroll();
  689.     AdjustText();
  690.     
  691. } // MyResizeWindow
  692.  
  693.  
  694.  
  695. // ==============================================
  696. void MyGrowWindow(WindowPtr w, Point p)
  697. {
  698.     GrafPtr        savePort;
  699.     long        theResult;
  700.     Rect        r;
  701.     
  702.     GetPort(&savePort);
  703.     SetPort(w);
  704.  
  705.     GetMaxGrowRect(w, &r);    
  706.     theResult = GrowWindow(w, p, &r);
  707.     if (theResult != 0)
  708.         MyResizeWindow(w, LoWord(theResult), HiWord(theResult));
  709.  
  710.     SetPort(savePort);
  711. } // MyGrowWindow
  712.  
  713.  
  714.  
  715. // ==============================================
  716. int CloseMyWindow(void)
  717. {
  718.  
  719.     if (gSrcWind_VRefNum != 0)
  720.     {
  721.         WriteFilePrefs();    // Save window info
  722.         // OK, now we're done with this file, release the pesky Working Directory
  723. //        CloseWD(gSrcWind_VRefNum);
  724.         gSrcWind_VRefNum = 0;
  725.     }
  726.  
  727.     // if there's a window (always) then hide it
  728.     if (gSrcWind_Window)
  729.         HideWindow(gSrcWind_Window);
  730.     gSrcWind_visible = false;
  731.  
  732.     // Image window also no longer valid!
  733.     CloseImageWindow();
  734.     gImageWindIsValid = false;
  735.  
  736.     // get rid of TE text (select all & delete)
  737.     if (gSrcWind_TEH)
  738.     {
  739.         TESetSelect(0, (**gSrcWind_TEH).teLength, gSrcWind_TEH);
  740.         TEDelete(gSrcWind_TEH);
  741.     }
  742.  
  743.     SetVScroll();
  744.  
  745.     SetUpFiles();
  746.  
  747.     return 0; // should be void fn!?
  748. }
  749.  
  750.  
  751.  
  752. // ==============================================
  753. main_init() 
  754. {
  755.     gSrcWind_Window = NULL;
  756.     SetUpFiles();
  757.     PreInitWindows();
  758. }
  759.  
  760.  
  761. // ==============================================
  762. int DoEditMouseDown(int windowPart, WindowPtr whichWindow, EventRecord *myEvent)
  763. {
  764.     switch (windowPart) {
  765.         case inGoAway:
  766.             if (ours(whichWindow) && (gDoingRender == 0))
  767.                 if (TrackGoAway(gSrcWind_Window, myEvent->where))
  768.                     DoFile(fmn_close);
  769.             break;
  770.  
  771.         case inDrag:
  772.             if (ours(whichWindow))
  773.             {
  774.                 SelectWindow(whichWindow);
  775.                 DragWindow(whichWindow, myEvent->where, &gDragBounds);
  776.                 GetGlobalWindowRect(whichWindow, &(**gFilePrefs_h).srcWind_pos);
  777.             }
  778.             break;
  779.  
  780.         case inGrow:
  781.             if (ours(whichWindow))
  782.                 MyGrowWindow(whichWindow, myEvent->where);
  783.             break;
  784.  
  785.         case inZoomIn:
  786.         case inZoomOut:
  787.             SelectWindow(whichWindow);
  788.             if (TrackBox(whichWindow, myEvent->where, windowPart))
  789.             {
  790.                 EraseRect(&((WindowPtr)whichWindow)->portRect);
  791.                 ZoomWindow((WindowPtr)whichWindow, windowPart, (WindowPtr)whichWindow==FrontWindow());
  792.                 MyResizeWindow(whichWindow,
  793.                         whichWindow->portRect.right - whichWindow->portRect.left,
  794.                         whichWindow->portRect.bottom - whichWindow->portRect.top);
  795.             }
  796.             break;
  797.  
  798.         case inContent:
  799.             if (whichWindow != FrontWindow())
  800.                 SelectWindow(whichWindow);
  801.             else if (ours(whichWindow))
  802.                 DoContent(whichWindow, myEvent);
  803.             break;
  804.     }
  805.     return 0; // should be void fn!?
  806. }
  807.  
  808.  
  809.  
  810. // ==============================================
  811. int MaintainCursor(void)
  812. {
  813.     Point        pt;
  814.     WindowPeek    wPtr;
  815.     GrafPtr        savePort;
  816.     
  817.     if (ours((WindowPtr)(wPtr=(WindowPeek)FrontWindow()))) {
  818.         GetPort(&savePort);
  819.         SetPort((GrafPtr)wPtr);
  820.         GetMouse(&pt);
  821.         if (PtInRect(pt, &(**gSrcWind_TEH).viewRect ) )
  822.             SetCursor( &gEditCursor);
  823.         else
  824.             SetCursor(&qd.arrow);
  825.         SetPort(savePort);
  826.     }
  827.     return 0; // should be void fn!?
  828. }
  829.  
  830.  
  831. // ==============================================
  832. #if defined(_DO_PRINTING_SOMEDAY_)
  833.  
  834. #define topMargin 20
  835. #define leftMargin 20
  836. #define bottomMargin 20
  837. #define tabChar    ((char)'\t')
  838.  
  839.  
  840. static    THPrint    hPrint = NULL;
  841. static    int        tabWidth;
  842.  
  843.  
  844.     /**
  845.      **        Prototypes for private functions.
  846.      **        (They really should be static.)
  847.      **
  848.      **/
  849.  
  850. int    CheckPrintHandle(void);
  851. int MyDrawText(char *p, int count);
  852. int PrDoc(char **hText, long count, THPrint hPrint, int font, int size);
  853. int HowMany(void);
  854.  
  855.  
  856. // ==============================================
  857. PleaseWait()
  858. {
  859.     SetCursor(&gWaitCursor);
  860. }
  861.  
  862.  
  863. // ==============================================
  864. CheckPrintHandle()
  865. {
  866.     if (hPrint==NULL) 
  867.         PrintDefault(hPrint = (TPrint **) NewHandle(sizeof( TPrint)));
  868. }
  869.  
  870.  
  871. // ==============================================
  872. DoPageSetUp()
  873. {
  874.     PrOpen();
  875.     CheckPrintHandle();
  876.     if (PrStlDialog(hPrint)) ;
  877.     PrClose();
  878. }
  879.  
  880.  
  881. // ==============================================
  882. MyDrawText(char    *p, int count)
  883. {
  884.     register char    *p1, *p2;
  885.     int                len;
  886.     Point            pt;
  887.  
  888.     p1 = p;
  889.     p2 = p+count;
  890.     while (p<p2) {
  891.         while ((p1<p2) && (*p1 !=tabChar)) *p1++;
  892.         if ((len=p1-p)>0) DrawText(p, 0, p1-p);
  893.         if (*p1==tabChar) {
  894.             GetPen(&pt);
  895.             Move((tabWidth-(pt.h-leftMargin)%tabWidth), 0);
  896.             *p1++;
  897.         }
  898.         p = p1;
  899.     }
  900. }
  901.  
  902.  
  903. // ==============================================
  904. PrDoc(char **hText, long count, THPrint hPrint, int font, int size)
  905. {
  906.     register int     line = 0;
  907.     register int     lastLineOnPage = 0;
  908.     int                length;
  909.     Rect             printRect;
  910.     int             linesPerPage;
  911.     int             lineBase;
  912.     int             lineHeight;
  913.     register char     *ptr, *p1;
  914.     FontInfo        info;
  915.     TPPrPort        printPort;
  916.  
  917.     printPort = PrOpenDoc(hPrint, 0L, 0L);
  918.     SetPort((GrafPtr)printPort);
  919.     TextFont(font);
  920.     TextSize(size);
  921.     printRect = (**hPrint).prInfo.rPage;
  922.     GetFontInfo(&info);
  923.     lineHeight = info.leading+info.ascent+info.descent;
  924.     linesPerPage = 
  925.         (printRect.bottom-printRect.top-topMargin-bottomMargin)/lineHeight;
  926.     HLock(hText);
  927.     ptr = p1 = (*hText);
  928.     do {
  929.         PrOpenPage(printPort, 0L);
  930.         lastLineOnPage += linesPerPage;
  931.         MoveTo( printRect.left+leftMargin, 
  932.             (lineBase = printRect.top+lineHeight) );
  933.         do {
  934.             /* PrintLine: */
  935.             while ((ptr<=(*hText)+count) && (*ptr++ != (char)'\r')) ;
  936.             if ((length=(int)(ptr-p1)-1)>0)
  937.                 MyDrawText(p1, length);
  938.             MoveTo( printRect.left+leftMargin, (lineBase += lineHeight));
  939.             p1 = ptr;
  940.         } while ((++line != lastLineOnPage) && (ptr<(*hText)+count));
  941.         PrClosePage(printPort);
  942.     } while (ptr<(*hText)+count);
  943.     HUnlock(hText);
  944.     PrCloseDoc(printPort);
  945. }
  946.  
  947.  
  948. // ==============================================
  949. PrintText(char    **hText, long length, GrafPtr gp, int tabPixels)
  950. {
  951.     GrafPtr        savePort;
  952.     TPrStatus    prStatus;
  953.     int            copies;
  954.     
  955.     PrOpen();
  956.     CheckPrintHandle();
  957.     tabWidth = tabPixels;
  958.     SetCursor(&qd.arrow);
  959.     if (PrJobDialog(hPrint) != 0) {
  960.         PleaseWait();
  961.         GetPort(&savePort);
  962.         for (copies=HowMany(); copies>0; copies--) {
  963.             PrDoc (hText, length, hPrint, (*gp).txFont, (*gp).txSize);
  964.             PrPicFile(hPrint, 0L, 0L, 0L, &prStatus);
  965.         }
  966.         SetPort(savePort);
  967.     }
  968.     PrClose();
  969. }
  970.  
  971.  
  972. // ==============================================
  973. int HowMany(void)
  974. {
  975.     return( ((**hPrint).prJob.bJDocLoop==bDraftLoop) ? 
  976.                 (**hPrint).prJob.iCopies : 1 );
  977. }
  978.  
  979. #endif // DO_PRINTING_SOMEDAY
  980.